package tech.xs.sys.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import tech.xs.auth.api.AuthTokenApi;
import tech.xs.auth.api.domain.bo.token.UpdateTokenBo;
import tech.xs.common.framework.domain.annotations.AuthApi;
import tech.xs.common.framework.domain.model.ApiResult;
import tech.xs.common.framework.util.Assert;
import tech.xs.common.sys.domain.constant.PermissionConstant;
import tech.xs.common.util.SyncUtil;
import tech.xs.sys.api.domain.SysRoleBo;
import tech.xs.sys.domain.bo.user.ListAllUserRoleBo;
import tech.xs.sys.domain.bo.user.role.EditUserRoleBo;
import tech.xs.sys.domain.entity.*;
import tech.xs.sys.service.SysRoleService;
import tech.xs.sys.service.SysUserRoleService;
import tech.xs.sys.service.SysUserService;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Slf4j
@Validated
@RestController
@RequestMapping("/user/role")
public class SysUserRoleController {

    @Resource
    private SysUserRoleService sysUserRoleService;
    @Resource
    private SysUserService sysUserService;
    @Resource
    private SysRoleService sysRoleService;
    @Resource
    private AuthTokenApi authTokenApi;

    @PostMapping("/saveOrUpdate")
    @AuthApi(permissions = PermissionConstant.USER_EDIT)
    public ApiResult<Void> manualEdit(@Validated @RequestBody EditUserRoleBo bo) {
        String userName = bo.getUserName();
        SysUser user = sysUserService.getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUserName, userName));
        Assert.isTrue(user != null, "用户不存在");
        if (!bo.getRoleCodes().isEmpty()) {
            long existPermission = sysRoleService.count(Wrappers.<SysRole>lambdaQuery()
                    .in(SysRole::getCode, bo.getRoleCodes()));
            Assert.isTrue(existPermission > 0, "权限不存在");
        }

        List<SysUserRole> saveDataList = new ArrayList<>();
        Set<String> roles = bo.getRoleCodes();
        if (roles != null) {
            for (String role : roles) {
                SysUserRole sysUserRole = new SysUserRole();
                sysUserRole.setUserName(userName);
                sysUserRole.setRoleCode(role);
                saveDataList.add(sysUserRole);
            }
        }
        List<SysUserRole> dbDataList = sysUserRoleService.list(Wrappers.<SysUserRole>lambdaQuery().eq(SysUserRole::getUserName, userName));

        List<SysUserRole> addList = new ArrayList<>();
        List<SysUserRole> updateList = new ArrayList<>();
        List<SysUserRole> deleteList = new ArrayList<>();
        SyncUtil.contrast(saveDataList, dbDataList, addList, updateList, deleteList, new SyncUtil.Compare<SysUserRole>() {
            @Override
            public boolean compare(SysUserRole o1, SysUserRole o2) {
                return o1.getRoleCode().equals(o2.getRoleCode()) && o1.getUserName().equals(o2.getUserName());
            }

            @Override
            public SysUserRole sourceToTarget(SysUserRole source, SysUserRole target) {
                source.setId(target.getId());
                return source;
            }
        });

        log.info("更新用户权限 addList:" + addList + " updateList:" + updateList + " deleteList:" + deleteList);
        if (!addList.isEmpty()) {
            sysUserRoleService.saveBatch(addList);
        }
        if (!updateList.isEmpty()) {
            sysUserRoleService.updateBatchById(updateList);
        }
        if (!deleteList.isEmpty()) {
            sysUserRoleService.removeBatchByIds(deleteList);
        }
        UpdateTokenBo updateTokenBo = new UpdateTokenBo();
        updateTokenBo.setUserId(user.getId());
        authTokenApi.updateToken(updateTokenBo);

        return ApiResult.success();
    }

    @GetMapping("/getRoleCodesByUserName")
    public ApiResult<Set<String>> getRoleCodesByUserName(@RequestParam String userName) {
        return ApiResult.success(sysUserRoleService.getRoleCodesByUserName(userName));
    }


    @GetMapping("/getRolesByUserName")
    public ApiResult<List<SysRoleBo>> getRolesByUserName(@RequestParam String userName) {
        List<SysRole> roleList = sysUserRoleService.getRolesByUserName(userName);
        List<SysRoleBo> resData = BeanUtil.copyToList(roleList, SysRoleBo.class);
        return ApiResult.success(resData);
    }

    @GetMapping("/list/all")
    @AuthApi(permissions = {PermissionConstant.USER_EDIT})
    public ApiResult<List<SysUserRole>> listAll(@ModelAttribute ListAllUserRoleBo bo) {
        return ApiResult.success(sysUserRoleService.list(Wrappers.<SysUserRole>lambdaQuery()
                .eq(StrUtil.isNotBlank(bo.getUserName()), SysUserRole::getUserName, bo.getUserName())
                .orderByAsc(SysUserRole::getUserName, SysUserRole::getRoleCode)));
    }


}
